package com.h2cloud.testIO;

/**
 * @Package: com.h2cloud.testIO
 * @ClassName: FileTest
 * @Author: h2cloud
 * @CreateTime: 2021/4/15 11:37 上午
 * @Description:
 */

import org.junit.Test;

import java.io.File;

/**
 * File类的使用
 * <p>
 * 1. File类的一个对象，代表一个文件或一个文件目录(俗称：文件夹)
 * 2. File类声明在java.io包下
 */
public class FileTest {
    /**
     * 1.如何创建file类的实例
     * File(String filePath):以filePath为路径创建File对象，可以是绝对路径或者相对路径
     * File(String parentPath,String childPath):以parentPath为父路径，childPath为子路径创建File对象。
     * File(File parentFile,String childPath):根据一个父File对象和子文件路径创建File对象
     * 2.
     * 相对路径：相较于某个路径下，指明的路径。
     * 绝对路径：包含盘符在内的文件或文件目录的路径
     * <p>
     * 3.路径分隔符
     * windows:\\
     * unix:/
     * 4.Java程序支持跨平台运行，因此路径分隔符要慎用。
     * <p>
     * 5.为了解决这个隐患，File类提供了一个常量：
     * public  static final String separator。
     * 根据操作系统，动态的提供分隔符。
     * <p>
     * File file1= new File("d:\\Work\\info.txt");
     * File file2= new File("d:"+ File.separator+ "Work"+ File.separator+ "info.txt");
     * File file3= new File("d:/Work");
     */
    public static void main(String[] args) {
        // 递归:文件目录
        /** 打印出指定目录所有文件名称，包括子文件目录中的文件 */

        // 1.创建目录对象
        File dir = new File("/Users/h2cloud/Documents/第1部分：Java基础编程");

        // 2.打印目录的子文件
        listAllSubFiles(dir);
    }

    public static void printSubFile(File dir) {
        // 打印目录的子文件
        File[] subfiles = dir.listFiles();

        for (File f : subfiles) {
            if (f.isDirectory()) {// 文件目录
                printSubFile(f);
            } else {// 文件
                System.out.println(f.getAbsolutePath());
            }
        }
    }

    // 方式二：循环实现
    // 列出file目录的下级内容，仅列出一级的话
    // 使用File类的String[] list()比较简单
    public static void listSubFiles(File file) {
        if (file.isDirectory()) {
            String[] all = file.list();
            for (String s : all) {
                System.out.println(s);
            }
        } else {
            System.out.println(file + "是文件！");
        }
    }

    // 列出file目录的下级，如果它的下级还是目录，接着列出下级的下级，依次类推
    // 建议使用File类的File[] listFiles()
    public static void listAllSubFiles(File file) {
        if (file.isFile()) {
            System.out.println(file);
        } else {
            File[] all = file.listFiles();
            // 如果all[i]是文件，直接打印
            // 如果all[i]是目录，接着再获取它的下一级
            for (File f : all) {
                listAllSubFiles(f);// 递归调用：自己调用自己就叫递归
            }
        }
    }

    // 拓展1：求指定目录所在空间的大小
    // 求任意一个目录的总大小
    public long getDirectorySize(File file) {
        // file是文件，那么直接返回file.length()
        // file是目录，把它的下一级的所有大小加起来就是它的总大小
        long size = 0;
        if (file.isFile()) {
            size += file.length();
        } else {
            File[] all = file.listFiles();// 获取file的下一级
            // 累加all[i]的大小
            for (File f : all) {
                size += getDirectorySize(f);// f的大小;
            }
        }
        return size;
    }

    // 拓展2：删除指定的目录
    public void deleteDirectory(File file) {
        // 如果file是文件，直接delete
        // 如果file是目录，先把它的下一级干掉，然后删除自己
        if (file.isDirectory()) {
            File[] all = file.listFiles();
            // 循环删除的是file的下一级
            for (File f : all) {// f代表file的每一个下级
                deleteDirectory(f);
            }
        }
        // 删除自己
        file.delete();
    }

}

